package com.cwits.wifi.update;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;


public class UpdateChecker extends
		AsyncTask<URL, Integer, UpdateChecker.AppVersionInfo> {
	public static final String UPDATE_CHECKED_DAY_KEY = "update_checked_day";
	private LinkedList<IUpdateCheckerListener> mListeners = new LinkedList<IUpdateCheckerListener>();
	private String DOWN_URL = "";

	private Context mContext;
	PackageManager mPackMgr;
	PackageInfo mPackInfo;

	public UpdateChecker(Context context) {
		mContext = context;
		mPackMgr = mContext.getPackageManager();

		try {

			mPackInfo = mPackMgr.getPackageInfo(mContext.getPackageName(), 0);

		} catch (NameNotFoundException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}
	}

	public class AppVersionInfo {
		public int mVersionCode;
		public String mVersionName;
		public String mVersionURL;
		public String mVersionURL_YingYongBao;//应用宝渠道
		public String mVersionURL_YYB_OFFICIAL;//在官网指向应用宝

		public AppVersionInfo(int verCode, String verName, String verURL,String verURL_Yingyongbao,String verURL_yyb_official) {
			
			mVersionCode = verCode;
			mVersionName = verName;
			mVersionURL = verURL;
			mVersionURL_YingYongBao = verURL_Yingyongbao;
			mVersionURL_YYB_OFFICIAL = verURL_yyb_official;
		}
	}

	public interface IUpdateCheckerListener {
		/**
		 * �Զ�����°汾����¼�
		 * 
		 * @param needUpdate
		 *            true������°汾��falseû���°汾
		 * @param verInfo
		 *            ���Ϊnull���汾��Ϣ��null��������ִ���
		 */
		void onUpdateCheckResult(boolean needUpdate, AppVersionInfo verInfo);
	}

	/**
	 * ����listener
	 * 
	 * @param listener
	 *            ������
	 * @return true���ɹ�������false
	 */
	public boolean addUpdateCheckerListener(IUpdateCheckerListener listener) {
		if (null != listener) {
			mListeners.remove(listener);
			return mListeners.add(listener);
		} else {
			return false;
		}
	}

	/**
	 * ɾ��listener
	 * 
	 * @param listener
	 *            ������
	 * @return true���ɹ�������false
	 */
	public boolean removeUpdateCheckerListener(IUpdateCheckerListener listener) {
		if (null != listener) {
			return mListeners.remove(listener);
		} else {
			return false;
		}
	}

	@Override
	protected AppVersionInfo doInBackground(URL... params) {
		AppVersionInfo verInfo = new AppVersionInfo(0, "v1.0", "","","");
		URL url = null;
		HttpURLConnection urlConnection = null;

		try {
			Log.i("UpdateChecker", "Start check the new version...");
			// ���ذ汾�����ļ�
			DOWN_URL = "http://cross.kcnzq.net:8099/app/android/base/newapp/";
			url = new URL(DOWN_URL + "cwcex_version.xml");
			urlConnection = (HttpURLConnection) url.openConnection();
			InputStream in = new BufferedInputStream(
					urlConnection.getInputStream());

			// ׼�������汾�����ļ�
			XmlPullParserFactory factory;
			factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(true);
			XmlPullParser xpp = factory.newPullParser();
			xpp.setInput(in, null);
			int eventType = xpp.getEventType();
			String tagName = new String("");
			boolean haveAndroidApp = false;
			boolean haveCurrVer = false;

			Log.i("UpdateChecker", "Begin to analyze the version data.");
			// ������ȡ�¼����������
			while (eventType != XmlPullParser.END_DOCUMENT) {
				if (eventType == XmlPullParser.START_TAG) {
					tagName = xpp.getName();
					if (!haveCurrVer) {
						if (tagName.equalsIgnoreCase("android_app")) {
							haveAndroidApp = true;
						} else if (haveAndroidApp
								&& tagName.equalsIgnoreCase("current_version")) {
							haveCurrVer = true;
						}
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					if (tagName.equalsIgnoreCase("android_app")) {
						haveAndroidApp = false;
						haveCurrVer = false;
						break;
					} else {
						tagName = new String("");
					}
				} else if (eventType == XmlPullParser.TEXT) {
					if (haveCurrVer) {
						if (tagName.equalsIgnoreCase("curr_ver_code")) {
							verInfo.mVersionCode = Integer.parseInt(xpp
									.getText());
						} else if (tagName.equalsIgnoreCase("curr_ver_name")) {
							verInfo.mVersionName = xpp.getText();
						} else if (tagName.equalsIgnoreCase("curr_ver_url")) {
							verInfo.mVersionURL = xpp.getText();
						}else if (tagName.equalsIgnoreCase("curr_ver_url_yingyongbao")) {
							verInfo.mVersionURL_YingYongBao = xpp.getText();
						}else if (tagName.equalsIgnoreCase("curr_ver_url_yyb_official")) {
							verInfo.mVersionURL_YYB_OFFICIAL = xpp.getText();
						}
					}
				} else {
					tagName = new String("");
				}
				eventType = xpp.next();
			}
			Log.i("UpdateChecker", "Analyze the version data completed.");
		} catch (MalformedURLException e) {
			verInfo = null;
			e.printStackTrace();
		} catch (IOException e) {
			verInfo = null;
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			verInfo = null;
			e.printStackTrace();
		} finally {
			if (null != urlConnection)
				urlConnection.disconnect();
		}

		// ���ذ汾˵����Ϣ�ļ�
		if ((null != verInfo) && (verInfo.mVersionCode > mPackInfo.versionCode)) {

			downloadVersionInfoFile(verInfo.mVersionCode);
		}

		return verInfo;
	}

	/**
	 * 下载更新信息
	 * 
	 * @param mVersionCode
	 */
	private boolean downloadVersionInfoFile(int mVersionCode) {
		URL url;
		HttpURLConnection connVerDesc = null;
		String verDescFileName = "cwcex_version_desc_"
				+ Integer.toString(mVersionCode) + ".xml";
		File verDescFilePath = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath()
				+ "/lipeibao/168cardev/"
				+ "VersionFiles/");
		boolean result = false;

		try {
			if(!verDescFilePath.exists())
				verDescFilePath.mkdirs();
			File verDescFile = new File(Environment.getExternalStorageDirectory()
					.getAbsolutePath()
					+ "/lipeibao/168cardev/"
					+ "VersionFiles/" + verDescFileName);
			if (!verDescFile.exists()) {
				url = new URL(DOWN_URL + verDescFileName);
				connVerDesc = (HttpURLConnection) url.openConnection();
				if (connVerDesc != null && !connVerDesc.equals("")) {
					InputStream inVerDesc = new BufferedInputStream(
							connVerDesc.getInputStream());
					OutputStream outFile = new BufferedOutputStream(
							new FileOutputStream(verDescFile));

					byte b = 0;
					while ((b = (byte) inVerDesc.read()) != -1) {
						outFile.write(b);
					}

					inVerDesc.close();
					outFile.close();

					result = true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != connVerDesc)
				connVerDesc.disconnect();
		}

		return result;
	}

	@Override
	protected void onPostExecute(AppVersionInfo result) {
		if (null == result) {
			notifyAllListener(false, null);
			return;
		}

		Log.i("UpdateChecker", "verCode:"
				+ Integer.valueOf(result.mVersionCode).toString() + " verName:"
				+ result.mVersionName + " verURL:" + result.mVersionURL);
		/* ����˴μ��ʱ�� */
		// CEXContext.getPreference(CEXContext.getCurrentCexNumber()).setPreference(
		// new KeyValuePair(UPDATE_CHECKED_DAY_KEY, Long.valueOf(
		// System.currentTimeMillis()).toString()));

		/* ֪ͨ�¼������� */
		if (result.mVersionCode > mPackInfo.versionCode) {
			notifyAllListener(true, result);
		} else {
			notifyAllListener(false, result);
		}

		super.onPostExecute(result);
	}

	private void notifyAllListener(boolean needUpdate, AppVersionInfo verInfo) {
		for (int i = 0; i < mListeners.size(); ++i) {
			mListeners.get(i).onUpdateCheckResult(needUpdate, verInfo);
		}
	}

}
